/**
 * Math utilities used for different computations
 * @author Cem Altel
 * @author Alex Bruck
 * @author Paula Gonz�lez Mu�oz
 */
class MathUtil
{
	
	/**
	 * manual implementation of atan2() since j2me does not support it
	 * @param y - Y coordinate
	 * @param x - X coordinate
	 * @return returns the angle
	 */
	public static double aTan2 (double y, double x)
    {
		// Special cases.
		if ( Double.isNaN(y) || Double.isNaN(x) )
		{
			return Double.NaN;
		}
		else if ( Double.isInfinite(y) )
		{
			if ( y > 0.0 ) // Positive infinity
			{
				if ( Double.isInfinite(x) )
				{
					if ( x > 0.0 )
					{
						return Math.PI/4;
					}
					else
					{
						return 3.0 * Math.PI/4;
					}
				}
				else if ( x != 0.0 )
				{
					return Math.PI/2;
				}
			}
			else  // Negative infinity
			{
				if ( Double.isInfinite(x) )
				{
					if ( x > 0.0 )
					{
						return -Math.PI/4;
					}
					else
					{
						return -3.0 * Math.PI/4;
					}
				}
				else if ( x != 0.0 )
				{
					return -Math.PI/2;
				}
			}
		}
		else if ( y == 0.0 )
		{
			if ( x > 0.0 )
			{
				return y;
			}
			else if ( x < 0.0 )
			{
				return Math.PI;
			}
		}
		else if ( Double.isInfinite(x) )
		{
			if ( x > 0.0 )  // Positive infinity
			{
				if ( y > 0.0 )
				{
					return 0.0;
				}
				else if ( y < 0.0 )
				{
					return -0.0;
				}
			}
			else  // Negative infinity
			{
				if ( y > 0.0 )
				{
					return Math.PI;
				}
				else if ( y < 0.0 )
				{
					return -Math.PI;
				}
			}
		}
		else if ( x == 0.0 )
		{
			if ( y > 0.0 )
			{
				return Math.PI/2;
			}
			else if ( y < 0.0 )
			{
				return -Math.PI/2;
			}
		}
		double arcTangent;
		// Use arctan() avoiding division by zero.
		if ( Math.abs(x) > Math.abs(y) )
		{
			arcTangent = aTan(y / x);
		}
		else
		{
			arcTangent = aTan(x / y); // -PI/4 <= a <= PI/4
			if ( arcTangent < 0 )
			{
				arcTangent = -Math.PI/2 - arcTangent; // a is negative, so we're adding
			}
			else
			{
				arcTangent = Math.PI/2 - arcTangent;
			}
		}
		// Adjust result to be from [-PI, PI]
		if ( x < 0 )
		{
			if ( y < 0 )
			{
				arcTangent = arcTangent - Math.PI;
			}
			else
			{
				arcTangent = arcTangent + Math.PI;
			}
		}
		return arcTangent;
    }

	/**
	 * manual calculation of an atan
	 * @param a - value of the tangent
	 * @return - angle
	 */
	public static double aTan (double a)
    {
		double ATAN_CONSTANT = 1.732050807569;
		// Special cases.
		if ( Double.isNaN(a) )
		{
			return Double.NaN;
		}
		if ( a == 0.0 )
		{
			return a;
		}
		// Compute the arc tangent.
		boolean negative = false;
		boolean greaterThanOne = false;
		int i = 0;
            
		if ( a < 0.0 )
		{
			a = -a;
			negative = true;
		}

		if ( a > 1.0 )
		{
			a = 1.0 / a;
			greaterThanOne = true;
		}
		double t;
		for ( ; a > Math.PI/12; a *= t )
		{
			i++;
			t = a + ATAN_CONSTANT;
			t = 1.0 / t;
			a *= ATAN_CONSTANT;
			a--;
		}

		double aSquared = a * a;
        
		double arcTangent = aSquared + 1.4087812;
		arcTangent = 0.55913709 / arcTangent;
		arcTangent += 0.60310578999999997;
		arcTangent -= 0.051604539999999997 * aSquared;
		arcTangent *= a;

		for ( ; i > 0; i-- )
		{
			arcTangent += Math.PI/6;
		}
		if ( greaterThanOne )
		{
			arcTangent = Math.PI/2 - arcTangent;
		}
		if ( negative )
		{
			arcTangent = -arcTangent;
		}
		return arcTangent;
    }
}